<?php
/** This class performs sorting operations
* @see Url, Pager
*/
class Sorter
{
    /** aliases of available for sorting fields
     * @var array
     */
    var $fields = array();

    /** currently selected for sorting fields
     * @var array
     */
    var $selected = array();

    /** key in url for storing field for sorting
     * @var string
     */
    var $urlKey = 'srt';

    /** name of imgages
     * @var array
     */
    var $aImg = array(
                'up'    => 'up.gif',
                'down'  => 'down.gif',
                'empty' => '0.gif',
                'plus'  => 'plus.gif',
                'minus' => 'minus.gif'
    );


    /**
     * Creates sorting info
     * @access public
     * @param object $url current url
     * @param string $urlKey prefix of names of sorting params in url
     * @param string $urlPageKey name of page param in url
     * @return object Sorter
     */
    function Sorter($url, $urlKey='srt', $urlPageKey='page')
    {
        $this->url    = $url;
        $this->url->setParam($urlPageKey, null);

        $this->urlKey = $urlKey;
    }

    /**
     * Inits sorter
     * @access public
     * @param array $fields fields for sorting
     * @return string data for sql `order by` statement
     */
    function init($fields)
    {
        $this->fields = $fields;

        $n = sizeof($this->fields);
        for ($i=0; $i<$n; ++$i)
        {
            list($fld, $srt) = $this->_get($i);
            if (in_array($fld, $this->fields))
                $this->selected[$i] = array($fld, $srt);
        }

        if (!$this->selected)
        {
            $this->selected[0] = array($this->fields[0], 'down');
            $this->_set($this->url, 0, $this->fields[0], 'down');
        }
        return $this->getOrder();
    }

    /**
     * Returns sorting info: array of urls/images
     * @access public
     * @return array
     * @see Sorter::show()
     */
    function getInfo()
    {
        // array url,img, set
        $info = array();
        $n = sizeof($this->selected);

        list($fld, $srt) = $this->_get(0);
        if (1 == $n && !$fld)
            $n--;

        //clear url
        $urlNew = $this->url;
        for ($i=0; $i<$n; ++$i)
            $this->_set($urlNew, $i);

        //set params for all fielsd
        foreach ($this->fields as $sField)
        {
            //set sorting
            $this->_set($urlNew, 0, $sField, 'up');
            $info[$sField]['url'] = $urlNew->getUrl();
            $this->_set($urlNew, 0);

            //image for current sorting
            $info[$sField]['img'] = $this->aImg['empty'];

            //add to existing sorting
            $this->_set($this->url, $n, $sField, 'up');
            $info[$sField]['url_set'] = $this->url->getUrl();
            $this->_set($this->url, $n);

            // image for status
            $info[$sField]['img_set'] = $this->aImg['plus'];

            // num for alt
            $info[$sField]['num'] = '';
        }

        //for selected
        foreach ($this->selected as $i=>$aRow)
        {
            list($sField, $sDir) = $aRow;
            $url = $this->url;

            //set sorting
            $this->_set($url, $i, $sField, 'up'==$sDir ? 'down':'up');
            $info[$sField]['url'] = $url->getUrl();

            //image for current sorting
            $info[$sField]['img'] = $this->aImg['up'==$sDir ? 'down':'up'];

            //remove from existing sorting
            for ($j=$i; $j<$n-1; ++$j)
            {
                list($f, $s) = $this->_get($j+1);
                $this->_set($url, $j, $f, $s);
            }

            //remove last
            $this->_set($url, $n-1);
            $info[$sField]['url_set'] = $url->getUrl();

            // image for status
            $info[$sField]['img_set'] = $this->aImg[$n<2?'empty':'minus'];

            // num for alt
            $info[$sField]['num'] = $i;
        }
        return $info;
    }

    /** Prepares string for sql 'order by' statement
    * @return string
    */
    function getOrder()
    {
        $aOrder = array();
        foreach($this->selected as $aRow)
            $aOrder[] = $aRow[0].' '.( $aRow[1] == 'up' ? 'ASC' : 'DESC');
        return join(',', $aOrder);
    }

    /** Shows table header for given sorting column with given title
    */
    function show($val, $title, $class = 'sorter_link')
    {
        $html = '';
        $html  = '<table cellspacing="0" cellpadding="0"><tr>';
        $html .= '<td><a title="Position '.$val['num'].'" class="'. $class .'" href="'.$val['url'].'">'.$title.'</a></td>';
        $html .= '<td><img width="10" height="7" border="0" src="/pic/'.$val['img'].'" /></td></tr></table>';
        echo $html;
    }

    /** Gets sorting params from current url
     * @param int $i position
     * @return array(sorting field, sorting orser)
     */
    function _get($i)
    {
        $i = ($i ? $i : '');
        $srt = 'up';
        $fld =  $this->url->getParam($this->urlKey.$i);
        $ind = strrpos($fld, '_');
        if (false !== $ind)
        {
            $srt = substr($fld, $ind+1) == 'up' ? 'up' : 'down';
            $fld = substr($fld, 0, $ind);
        }
        return array($fld, $srt);
    }

    /**
     * Sets sorting params to given url.
     * @param Url url to set params
     * @param int $i position
     * @param string $fld sorting field
     * @param string $srt sorting order
     * @return void
     */
    function _set($url, $i, $fld=null, $srt=null)
    {
        $i = ($i ? $i : '');
        $fld = ($fld ? $fld.'_'.$srt : null);
        $url->setParam($this->urlKey.$i, $fld);
    }
}
?>
